package matrix;

import Jama.*;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import java.util.Hashtable;

/**
 *
 * @author Nikea Davis, Kevin Dominique, Robert Martinez
 */
public class MatrixCalculator {

    Hashtable <String,Matrix> matrices = new Hashtable();
    
public double[] EigenValue(Matrix a){
    /*Calculates and returns the eigen values of matrix a*/
    EigenvalueDecomposition e=a.eig();
    return e.getRealEigenvalues();
}

public void CreateNewMatrix(int row, int col, String name){
    /*creates new Matrix Object with size (row,col) and adds it to matrices
     LinkedList*/
    Matrix matrix = new Matrix (row, col);   
    matrices.put(name, matrix);
}

public Matrix getMatrix(String matrixName){
return matrices.get(matrixName);
}


public void InputData(int row, int col, double value,String matrixName){
   /*removes matrix from hashtable so that it can be replaced
    inserts the value into the matrix
    puts new matrix into hashtable*/
   
Matrix newMatrix=matrices.remove(matrixName); 
    newMatrix.set(row-1,col-1,value);
    matrices.put(matrixName,newMatrix);
}

public void DeleteMatrix(Matrix deleted){
    /*Removes deleted from the matrices LinkedList*/

}


    public void printOut(String matrixName, Matrix a, int numOfColumns, JTextArea outputWindow) {
        /*outputs printed to UI text area*/

        double[][] matrixArray = a.getArray();

        DecimalFormat format = new DecimalFormat();
        format.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US));
        format.setMinimumIntegerDigits(1);
        format.setMaximumFractionDigits(0);
        format.setMinimumFractionDigits(0);
        format.setGroupingUsed(false);
        
        outputWindow.append("Matrix: "+ matrixName);
        outputWindow.append("\n");// space between matrix name and matrix values

        for (int i = 0; i < a.getRowDimension(); i++) {

            for (int j = 0; j < a.getColumnDimension(); j++) {
                String s = format.format(matrixArray[i][j]); // get string representation of double
                int padding = Math.max(1, numOfColumns - s.length()); // At _least_ 1 space

                for (int k = 0; k < padding; k++) {
                    outputWindow.append(" ");
                }
                outputWindow.append(s);
            }
            outputWindow.append("\n");//next row  
        }
        outputWindow.append("\n");// end with blank line.
    }

    public void printOut(String str, JTextArea outputWindow){
         outputWindow.append(str);
        outputWindow.append("\n");
    }

    public Matrix Multiply(Matrix a, Matrix b) {
        Matrix c = null;
        try {
           c= a.times(b);
        } catch (IllegalArgumentException e) {
            JOptionPane.showMessageDialog(null, "Matrix dimensions do not agree.");
        }
        
        return c;
    }

    public Matrix DotProduct(Matrix a, Matrix b) {
        Matrix c = null;
        /*Check if a and b are vectors*/

        int aCols = a.getColumnDimension();
        int aRows = a.getRowDimension();

        int bCols = b.getColumnDimension();
        int bRows = b.getRowDimension();



        /*Dot Product = a Transpose x b*/
        if (aRows == bRows) {
            a = a.transpose();
        }
        return a.times(b);
    }

    public Matrix Inverse(Matrix a) {
        return a.inverse();
    }

    public Matrix Transpose(Matrix a) {
        return a.transpose();
    }

    public double Determinate(Matrix a) {
        double determinate= 0;
        
        if (a.getColumnDimension() != a.getRowDimension()) {
            JOptionPane.showMessageDialog(null, "Matrix A is not square.");
           
        } else {
            determinate=a.det();
        }
        return determinate;
    }

    public Matrix LinearEquation(Matrix a, Matrix b) {

        /*AX=B
        Returns X*/
        return a.solve(b);
    }
    public Matrix NewtonIteration(Matrix a, Matrix b,Matrix c){
        Matrix result=null;

        b=b.inverse();
        Matrix bc=b.times(c);

        result =a.minus(bc);
        return result;

    }

    public SingularValueDecomposition SVD(Matrix a){
        return a.svd();
    }


    public SchurFactorization Schur(Matrix a,double eigValue){
  
SchurFactorization s = new SchurFactorization(a,eigValue);
        
    return s;

    }
}


